package com.yjb.demo.elasticsearch.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.util.Objects;

/**
 * @description 
 * @author yinjinbiao
 * @create 2024/1/5 10:43
 * @version 1.0
 */
@Data
public class ResponseResult<T> {


	/**
	 * 状态码
	 */
	private String code;

	/**
	 * 消息
	 */
	private String msg;

	/**
	 * 返回对象
	 */
	private T data;

	public static <T> ResponseResult<T> ok(){
		return newResponse(ErrorCodeEnum.SUCCESS.getCode(), ErrorCodeEnum.SUCCESS.getMsg(), null);
	}

	public static <T> ResponseResult<T> ok(T data){
		return newResponse(ErrorCodeEnum.SUCCESS.getCode(), ErrorCodeEnum.SUCCESS.getMsg(), data);
	}

	public static ResponseResult error(String code, String msg){
		return newResponse(code, msg, null);
	}

	public static <T> ResponseResult<T> newResponse(String code, String msg, T data) {
		ResponseResult<T> result = new ResponseResult<T>();
		result.setCode(code);
		result.setMsg(msg);
		if (data != null && data instanceof String && "".equals(data)) {
			result.setData(null);
		} else {
			result.setData(data);
		}
		return result;
	}

	@JsonIgnore // 避免 jackson 序列化
	public boolean isSuccess() {
		return isSuccess(code);
	}

	@JsonIgnore // 避免 jackson 序列化
	public boolean isError() {
		return !isSuccess();
	}

	public static boolean isSuccess(String code) {
		return Objects.equals(code, ErrorCodeEnum.SUCCESS.getCode());
	}

	// ========= 和 Exception 异常体系集成 =========

	/**
	 * 判断是否有异常。如果有，则抛出 {@link CustomException} 异常
	 */
	public void checkError() throws CustomException {
		if (isSuccess()) {
			return;
		}
		// 业务异常
		throw new CustomException(code, msg);
	}

	/**
	 * 判断是否有异常。如果有，则抛出 {@link CustomException} 异常
	 * 如果没有，则返回 {@link #data} 数据
	 */
	@JsonIgnore // 避免 jackson 序列化
	public T getCheckedData() {
		checkError();
		return data;
	}

	@Override
	public String toString() {
		return "{\"code\": " + this.getCode() + ", \"msg\": " + this.transValue(this.getMsg()) + ", \"data\": " + this.transValue(this.getData()) + "}";
	}

	private String transValue(Object value) {
		return value instanceof String ? "\"" + value + "\"" : String.valueOf(value);
	}
}
